<script lang="ts">
    import { onMount } from "svelte";
    import { VirtualListCore, type VirtualListStore } from "../VirtualList";
    import Cell from "./Cell.svelte";
    import Colgroup from "./Colgroup.svelte";
    import EmprtyRow from "./EmprtyRow.svelte";
    import Row from "./Row.svelte";
    import type { ColumnProps, TableStore } from "./Table";

    type BodyProps = {
        data: TableStore;
        onScroll: (scrollLeft: number, clientWidth: number, scrollWidth: number) => void;
        height?: number;
        rowKey: string;
        virtual?: boolean;
    };

    const props: BodyProps = $props();
    let body: any = $state();
    let contentElement: any = $state();
    let bodyElement: any = $state();
    const store = $derived<VirtualListStore>({
        scrollElement: body,
        contentElement: contentElement,
        bodyElement: bodyElement,
    });
    let height = $state<number>();
    const width = $derived.by(() => {
        const columns = props.data.columns;
        let total = 0;
        columns.forEach((item: ColumnProps) => {
            total += item._width || 0;
        });
        return total;
    });

    $effect(() => {
        // 数据改变也需要重刷
        props.data.data;
        props.height;
        const hh = props.data.headerSize.height;
        const summaryH = props.data.summarySize.height;

        if (props.virtual) {
            const scrollElHeight = props.height ?? document.documentElement.clientHeight;
            height = scrollElHeight - hh - summaryH;
        } else {
            Promise.resolve().then(() => {
                const content = body.querySelector(".cm-table-body-wrap");
                const contentH = content.getBoundingClientRect().height;
                if (props.height && contentH > props.height - hh - summaryH) {
                    const bodyH = props.height - hh - summaryH;
                    height = bodyH;
                }
                if (!props.height) {
                    height = undefined;
                }
            });
        }
    });

    const handleScroll = () => {
        props.onScroll(body.scrollLeft, body.clientWidth, body.scrollWidth);
    };
</script>

<div class="cm-table-body" bind:this={body} onscroll={handleScroll} style={`display: block; width: 100%; overflow: auto; height: ${height ? height + "px" : "auto"}; position: relative;`}>
    {#if props.virtual}
        <div bind:this={contentElement} style={`min-width: 100%; will-change: transform; box-sizing: border-box; position: absolute; top: 0; left: 0 `} style:width={width + "px"}>
            <table class="cm-table-body-wrap">
                <Colgroup data={props.data} />
                <thead style="display: none">
                    <tr>
                        {#each props.data.columns as col, index (col.name || col.type)}
                            <Cell column={col} type="th" placeholder colIndex={index} checkedAll={props.data.checkedAll} />
                        {/each}
                    </tr>
                </thead>
                <tbody bind:this={bodyElement}>
                    <VirtualListCore {store} items={props.data.data} itemEstimatedSize={48} maxHeight={height || props.height}>
                        {#snippet itemRender(item: any, index: number, itemProps: any)}
                            <Row data={item} {index} store={props.data} {...itemProps} />
                        {/snippet}
                    </VirtualListCore>
                    {#if !props.data.data || !props.data.data.length}
                        <EmprtyRow store={props.data} />
                    {/if}
                </tbody>
            </table>
        </div>
    {:else}
        <table class="cm-table-body-wrap">
            <Colgroup data={props.data} />
            <thead style="display: none">
                <tr>
                    {#each props.data.columns as col, index (col.name || col.type)}
                        <Cell column={col} type="th" placeholder colIndex={index} checkedAll={props.data.checkedAll} />
                    {/each}
                </tr>
            </thead>
            <tbody>
                {#each props.data.data as rowData, index (rowData[props.rowKey])}
                    <Row data={rowData} {index} store={props.data} />
                {/each}
                {#if !props.data.data || !props.data.data.length}
                    <EmprtyRow store={props.data} />
                {/if}
            </tbody>
        </table>
    {/if}
</div>
